package model

import (
	"context"
	"fmt"
	sq "github.com/Masterminds/squirrel"
	_ "github.com/lib/pq"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"time"
)

var _ StoreLogModel = (*customStoreLogModel)(nil)

type (
	// StoreLogModel is an interface to be customized, add more methods here,
	// and implement the added methods in customStoreLogModel.
	StoreLogModel interface {
		storeLogModel
		FindLatestByStoreId(ctx context.Context, id int64) (*StoreLog, error)
		FindCount(ctx context.Context, agentId, status int64, startTime, endTime time.Time) int64
	}

	customStoreLogModel struct {
		*defaultStoreLogModel
	}
)

// NewStoreLogModel returns a model for the database table.
func NewStoreLogModel(conn sqlx.SqlConn, c cache.CacheConf) StoreLogModel {
	return &customStoreLogModel{
		defaultStoreLogModel: newStoreLogModel(conn, c),
	}
}

func (m *defaultStoreLogModel) FindLatestByStoreId(ctx context.Context, id int64) (*StoreLog, error) {
	var resp StoreLog
	query := fmt.Sprintf("select %s from %s where store_id = $1 order by id desc limit 1", storeLogRows, m.table)
	err := m.QueryRowNoCacheCtx(ctx, &resp, query, id)
	switch err {
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

func (m *defaultStoreLogModel) FindCount(ctx context.Context, agentId, status int64, startTime, endTime time.Time) int64 {
	selectBuilder := sq.Select("min(id)").From(m.table)
	if status > -1 {
		selectBuilder = selectBuilder.Where(sq.Eq{"status": status})
	}
	if agentId > 0 {
		selectBuilder = selectBuilder.Where(sq.Eq{"agent_id": agentId})
	}

	if startTime != endTime {
		selectBuilder = selectBuilder.Where(sq.GtOrEq{"update_time": startTime}).Where(sq.LtOrEq{"update_time": endTime})
	}

	sqlBuilder := sq.Select("count(1)").FromSelect(selectBuilder.GroupBy("store_id"), "a")

	query, args, err := sqlBuilder.PlaceholderFormat(sq.Dollar).ToSql()
	if err != nil {
		return 0
	}
	var count int64
	err = m.QueryRowNoCacheCtx(ctx, &count, query, args...)
	if err != nil {
		return 0
	}
	return count

}
